package com.alks.function.controller.finance.lotcost;

import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.alks.common.aop.ApiRestController;
import com.alks.common.aop.AutoPageAop;
import com.alks.common.aop.WebLogger;
import com.alks.common.utils.BigDecimalUtil;
import com.alks.common.utils.ObjectToMapUtil;
import com.alks.common.utils.excelUtils.ExcelPoiUtils;
import com.alks.common.utils.excelUtils.ExcelUtils;
import com.alks.common.utils.excelUtils.data.ImageData;
import com.alks.entity.data.enums.LaborTypeEnum;
import com.alks.entity.data.enums.MtlEnum;
import com.alks.entity.data.response.ResponseInfo;
import com.alks.entity.exception.EmptyDataException;
import com.alks.entity.exception.ServiceErrorException;
import com.alks.function.data.request.finance.lotcost.LotCostRequest;
import com.alks.function.data.vo.finance.lotcost.LotCostAnalysisDetailVO;
import com.alks.function.data.vo.finance.lotcost.LotCostAnalysisListVO;
import com.alks.function.data.vo.finance.lotcost.ReportMtlDetailVO;
import com.alks.function.data.vo.finance.lotcost.ReportLaborDetailVO;
import com.alks.function.data.vo.stock.PageDataVO;
import com.alks.function.service.finance.lotcost.ILotCostAnalysisService;
import com.github.pagehelper.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author: chen
 * @date: 2024/12/20
 * @description: 指令成本分析
 */
@Slf4j
@RestController
@AllArgsConstructor
@ApiRestController("/lotCost/analysis")
@Api(value = "财务部", tags = "指令成本分析")
public class LotCostAnalysisController {

    final private ILotCostAnalysisService lotCostAnalysisService;

    final private Integer NUMBER_SCALE = 5;

    @WebLogger
    @PostMapping("/listPage")
    @ApiOperation(value = "分页查询", tags = "指令成本分析")
    @AutoPageAop
    public ResponseInfo<PageDataVO<LotCostAnalysisListVO>> tempQuery(@RequestBody LotCostRequest request) {
        PageDataVO<LotCostAnalysisListVO> res = new PageDataVO<>();
        List<LotCostAnalysisListVO> list = lotCostAnalysisService.tempQuery(request);
        Page<LotCostAnalysisListVO> page = (Page<LotCostAnalysisListVO>) list;
        res.setRows(list);
        res.setTotal(page.getTotal());
        return ResponseInfo.ok(res);
    }

    @WebLogger
    @PostMapping("/list/export")
    @ApiOperation(value = "导出列表", tags = "指令成本分析")
    public void listExport(@RequestBody LotCostRequest request, HttpServletResponse response) {
        request.setPageNum(1);
        request.setPageSize(Integer.MAX_VALUE);

        TemplateExportParams templateParams = new TemplateExportParams("templates/lot_cost_list.xlsx", true);
        templateParams.setColForEach(true);
        try {
            ExcelUtils.setResponseZF(response, "指令成本列表.xlsx");
            List<LotCostAnalysisListVO> reportDataVO = lotCostAnalysisService.tempQuery(request);
            if (!reportDataVO.isEmpty()) {
                List<ImageData> imageDataList = new ArrayList<>();
                for (int i = 0; i < reportDataVO.size(); i++) {
                    imageDataList.add(new ImageData(reportDataVO.get(i).getPhotoName(), 110, 50, 1 + i, 1));
                }
                ExcelPoiUtils.writeExcelByTemplateWithImages(response, templateParams, ObjectToMapUtil.convert(reportDataVO, "yyyy-MM-dd", NUMBER_SCALE), imageDataList);
            } else {
                throw new EmptyDataException("没有数据可以导出");
            }

        } catch (EmptyDataException e) {
            throw e;
        } catch (Exception e) {
            throw new ServiceErrorException("指令成本列表导出失败!");
        }
    }

    @WebLogger
    @GetMapping("/detail")
    @ApiOperation(value = "成本详情", tags = "指令成本分析")
    public ResponseInfo<LotCostAnalysisDetailVO> detail(@RequestParam String lotNo) {
        return ResponseInfo.ok(lotCostAnalysisService.detail(lotNo));
    }

    @WebLogger
    @GetMapping("/detail/export")
    @ApiOperation(value = "导出成本详情", tags = "指令成本分析")
    public void detailExport(@RequestParam String lotNo, HttpServletResponse response) {
        LotCostAnalysisDetailVO vo = lotCostAnalysisService.detail(lotNo);

        TemplateExportParams templateParams = new TemplateExportParams("templates/lot_cost_analysis.xlsx", true);
        templateParams.setColForEach(true);
        try {
            ExcelUtils.setResponseZF(response, "指令"+ lotNo +"成本详情"+ System.currentTimeMillis() +".xlsx");
            List<ImageData> imageData = Collections.singletonList(new ImageData(vo.getPhotoName(), 220, 400, 2, 14));
            ExcelPoiUtils.writeExcelByTemplateWithImages(response, templateParams, ObjectToMapUtil.convert(vo, "yyyy-MM-dd", NUMBER_SCALE), imageData);

        } catch (Exception e) {
            throw new ServiceErrorException("指令成本详情导出失败!");
        }
    }

    @WebLogger
    @GetMapping("/pack/list")
    @ApiOperation(value = "包装材料明细", tags = "指令成本分析")
    public ResponseInfo<List<ReportMtlDetailVO>> packList(@RequestParam String lotNo) {
        return ResponseInfo.ok(lotCostAnalysisService.getCostDetail(lotNo, MtlEnum.TYPE_PACK.getValue(), null));
    }

    @WebLogger
    @GetMapping("/pack/list/export")
    @ApiOperation(value = "导出包装材料明细", tags = "指令成本分析")
    public void packListExport(@RequestParam String lotNo, HttpServletResponse response) {

        TemplateExportParams templateParams = new TemplateExportParams("templates/lot_cost_detail_pack.xlsx", true);
        templateParams.setColForEach(true);
        try {
            ExcelUtils.setResponseZF(response, lotNo + "包装材料明细列表"+ System.currentTimeMillis() +".xlsx");
            List<ReportMtlDetailVO> reportDataVO = lotCostAnalysisService.getCostDetail(lotNo, MtlEnum.TYPE_PACK.getValue(), null);
            if (!reportDataVO.isEmpty()) {
                Map<String, Object> map = new HashMap<>();
                map.put("lotNo", lotNo);
                map.put("data", ObjectToMapUtil.convert(reportDataVO, "yyyy-MM-dd", NUMBER_SCALE));
                map.put("totalAmt", BigDecimalUtil.formatNumber(reportDataVO.stream()
                        .map(e -> e.getAmt() == null ? BigDecimal.ZERO : e.getAmt())
                        .reduce(BigDecimal.ZERO, BigDecimal::add), NUMBER_SCALE));
                ExcelPoiUtils.writeExcelByTemplateWithImages(response, templateParams, map, null);
            } else {
                throw new EmptyDataException("没有数据可以导出");
            }

        } catch (EmptyDataException e) {
            throw e;
        } catch (Exception e) {
            throw new ServiceErrorException("包装材料明细列表导出失败!");
        }
    }

    @WebLogger
    @GetMapping("/cut/list")
    @ApiOperation(value = "冲裁人工明细", tags = "指令成本分析")
    public ResponseInfo<List<ReportLaborDetailVO>> cutList(@RequestParam String lotNo) {
        return ResponseInfo.ok(lotCostAnalysisService.getLaborDetail(lotNo, LaborTypeEnum.CUT.getValue()));
    }

    @WebLogger
    @GetMapping("/cut/list/export")
    @ApiOperation(value = "导出冲裁人工明细", tags = "指令成本分析")
    public void cutListExport(@RequestParam String lotNo, HttpServletResponse response) {
        exportLaborList(lotNo, response, LaborTypeEnum.CUT);
    }

    @WebLogger
    @GetMapping("/manual/list")
    @ApiOperation(value = "手工人工明细", tags = "指令成本分析")
    public ResponseInfo<List<ReportLaborDetailVO>> manualList(@RequestParam String lotNo) {
        return ResponseInfo.ok(lotCostAnalysisService.getLaborDetail(lotNo, LaborTypeEnum.MANUAL.getValue()));
    }

    @WebLogger
    @GetMapping("/manual/list/export")
    @ApiOperation(value = "导出手工人工明细", tags = "指令成本分析")
    public void manualListExport(@RequestParam String lotNo, HttpServletResponse response) {
        exportLaborList(lotNo, response, LaborTypeEnum.MANUAL);
    }

    @WebLogger
    @GetMapping("/out/list")
    @ApiOperation(value = "外协人工明细", tags = "指令成本分析")
    public ResponseInfo<List<ReportLaborDetailVO>> outList(@RequestParam String lotNo) {
        return ResponseInfo.ok(lotCostAnalysisService.getLaborDetail(lotNo, LaborTypeEnum.OUT.getValue()));
    }

    @WebLogger
    @GetMapping("/out/list/export")
    @ApiOperation(value = "导出外协人工明细", tags = "指令成本分析")
    public void outListExport(@RequestParam String lotNo, HttpServletResponse response) {
        exportLaborList(lotNo, response, LaborTypeEnum.OUT);
    }

    @WebLogger
    @GetMapping("/stitch/list")
    @ApiOperation(value = "针车人工明细", tags = "指令成本分析")
    public ResponseInfo<List<ReportLaborDetailVO>> stitchList(@RequestParam String lotNo) {
        return ResponseInfo.ok(lotCostAnalysisService.getLaborDetail(lotNo, LaborTypeEnum.STITCH.getValue()));
    }

    @WebLogger
    @GetMapping("/stitch/list/export")
    @ApiOperation(value = "导出针车人工明细", tags = "指令成本分析")
    public void stitchListExport(@RequestParam String lotNo, HttpServletResponse response) {
        exportLaborList(lotNo, response, LaborTypeEnum.STITCH);
    }

    private void exportLaborList(String lotNo, HttpServletResponse response, LaborTypeEnum laborTypeEnum) {
        String templateUrl;
        switch (laborTypeEnum) {
            case CUT:
                templateUrl = "templates/lot_cost_detail_cut.xlsx";
                break;
            case MANUAL:
                templateUrl = "templates/lot_cost_detail_manual.xlsx";
                break;
            case OUT:
                templateUrl = "templates/lot_cost_detail_out.xlsx";
                break;
            case STITCH:
                templateUrl = "templates/lot_cost_detail_stitch.xlsx";
                break;
            default:
                throw new ServiceErrorException("系统错误");
        }
        TemplateExportParams templateParams = new TemplateExportParams(templateUrl, true);
        templateParams.setColForEach(true);
        try {
            ExcelUtils.setResponseZF(response, lotNo + laborTypeEnum.getValue() + "人工明细列表"+ System.currentTimeMillis() +".xlsx");
            List<ReportLaborDetailVO> reportDataVO = lotCostAnalysisService.getLaborDetail(lotNo, laborTypeEnum.getValue());
            if (!reportDataVO.isEmpty()) {
                Map<String, Object> map = new HashMap<>();
                map.put("lotNo", lotNo);
                map.put("data", ObjectToMapUtil.convert(reportDataVO, "yyyy-MM-dd", NUMBER_SCALE));
                map.put("totalPrice", BigDecimalUtil.formatNumber(reportDataVO.stream()
                        .map(e -> e.getPrice() == null ? BigDecimal.ZERO : e.getPrice())
                        .reduce(BigDecimal.ZERO, BigDecimal::add), NUMBER_SCALE));
                ExcelPoiUtils.writeExcelByTemplateWithImages(response, templateParams, map, null);
            } else {
                throw new EmptyDataException("没有数据可以导出");
            }

        } catch (EmptyDataException e) {
            throw e;
        }catch (Exception e) {
            throw new ServiceErrorException(laborTypeEnum.getValue() + "人工明细列表导出失败!");
        }
    }
}
